package battleship.field;

import java.util.Arrays;

import battleship.Loop;
import battleship.Setup;
import battleship.boat.Boat;
import battleship.boat.BoatEnum;
import battleship.player.Player;

public class Field {
	public static final int MAX = 26;
	public static final int MIN = 10;
	public static final int MAX_BOATS = 5;
	
	private static int width = 10;
	private static int height = 10;
	private boolean[][] field = new boolean[height][width]; //the field in which all the boats
	private Boat[] boats = new Boat[MAX_BOATS];
	
	
	public void reinitialize() {
		field = new boolean[height][width];
	}
	
	public void setBoat(Boat boat, int index)
	{
		this.boats[index] = boat;
	}
	
	/**
	 * This function checks if every boat is set
	 * 
	 * @param comments true if you want the function to print out the boat which isnt set up
	 * @return false when not all the boats are set
	 */
	public boolean getBoatsSet(boolean comments){ //check if all the boats are set

		for(int i = 0; i < boats.length; i++){

			for(int j = 0; j < boats[i].getLength(); j++){
				for(int k = 0; k < boats[i].getPositions()[j].length; k++){
					if(boats[i].getPositions()[j][k] == -1){

						if(comments){
							System.out.println();
							System.out.printf("%s\n", boats[i].getName());
						}
						return false;
					}
				}
			}
		}

		return true;
	}
	
	public Field() {
		boats[0] = new Boat(BoatEnum.mijnenveger);
		boats[1] = new Boat(BoatEnum.onderzeeer);
		boats[2] = new Boat(BoatEnum.kruiser);
		boats[3] = new Boat(BoatEnum.slagschip);
		boats[4] = new Boat(BoatEnum.vliegdekschip);
	}
	
	public Boat[] getBoats(){
		return boats;
	}
	
//	public boolean outOfBoundsX(int x){
//		if(x >= width || x < 0){
//			return true;
//		}
//		return false;
//	}
//	
//	public boolean outOfBoundsY(int y){
//		if(y >= height || y < 0){
//			return true;
//		}
//		return false;
//	}
	
	public String fieldToString(){ //returns the values for the field numerically, 0 0 1 1 1
		String completeField = "";												// 1 1 0 0 1 etc.
		
		
		for(int h = 0; h < height; h++){
	
			for (int w = 0; w < width; w++){
				String tempInt;
				
				if(field[h][w]){
					tempInt = "1";
				}
				else {
					tempInt = "0";
				}
				completeField += tempInt;
				
			}
		}
		return completeField;
	}
	
	/**
	 * checks if the boat gets hit,
	 * sets the boat as hit,
	 * sets the lasthitboat
	 * 
	 * @param position the position it needs to check
	 * @return true if the boat was hit, false if not
	 */
	public boolean getHit(int[] position){ //return true if boat gets hit + sets the boat on hit + sets lasthitboat
		int x = position[1];
		int y = position[0];
		
		for(int boat = 0; boat < getBoats().length; boat++){		//check for hit boats
			if(getBoats()[boat].isHit(new int[]{ y, x})){			//if the boat was hit
				
				getBoats()[boat].setHit(new int[]{ y, x});			//set where the boat is hit
				Loop.setLastHitBoat(getBoats()[boat]);				//set last hit boat
				field[y][x] = true;
				return true;										//the boat got hit
			}
		}
		field[y][x] = true;
		return false;												//the boat didnt get hit
	}
	
	public static int getWidth(){
		return width;
	}
	
	public Boat getBoatAt(int[] position)
	{
		for (int boat = 0; boat < getBoats().length; boat++)
		{
			for (int length = 0; length < getBoats()[boat].getLength(); length++)
			{
				if(Arrays.equals(getBoats()[boat].getPositions()[length], position))
				{
					return getBoats()[boat];
				}
			}
		}
		
		
		return null;
		
	}
	
	public Boat getBoatAt(String position)
	{
		String xVal; // 1
		String yVal; // a
		
		int y = -1;
		int x = -1;
		
		yVal = String.valueOf(position.charAt(0));
		
		for(int alphabet = 0; alphabet < Setup.getPositionMap().length; alphabet++)
		{
			if(yVal.equalsIgnoreCase(Setup.getPositionMap()[alphabet]))
			{
				y = alphabet;
				break;
			}
		}
		
		if (y == -1)
		{
			throw new IllegalArgumentException();
		}
		
		xVal = position.substring(1);
		
		x = Integer.parseInt(xVal);
		
		int realX = x - 1;
		int realY = y;
		
		return getBoatAt(new int[] {realY,realX});
	}
	
	public static void setWidth(int size){
		width = size;
		
		for(Player player : Setup.getPlayers())
		{
			if(player != null)
			{
				player.getField().reinitialize();
			}
		}
	}
	
	public static int getHeight(){
		return height;
	}
	
	public static void setHeight(int size){
		height = size;
		
		for(Player player : Setup.getPlayers())
		{
			if(player != null) { //safety check for initializing savedata
				player.getField().reinitialize();
			}
		}
	}
	
	public boolean[][] getField(){
		return field;
	}
	
	public static void setFieldSize(int size){
		Field.height = size;
		Field.width = size;
	}
	
	public boolean containsBoat(int[] position){ //y, x
		for(int i = 0; i < getBoats().length; i++){							//loop for going through every boat
			for(int j = 0; j < getBoats()[i].getPositions().length; j++){	//loop for going through every pos of a boat
				if(getBoats()[i].getPositions()[j] == position){
					return true;
				}
			}
			
		}
		return false;
	}
	
	
}
